package com.mgee.netty.server.service;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.google.protobuf.Any;
import com.mgee.netty.server.constant.MessagingConst;
import com.mgee.netty.server.netty.IoSession;
import com.mgee.netty.server.netty.SessionManager;
import com.mgee.netty.server.pojo.ChatUserInfo;
import com.mgee.netty.server.pojo.LobbyInfo;
import com.mgee.netty.server.pojo.LobbyRoomInfo;
import com.mgee.netty.server.protobuf.ImProto.ImMsg;
import com.mgee.netty.server.protobuf.ImProto.JoiRoomInLobbyRequest;
import com.mgee.netty.server.protobuf.ImProto.JoinRoomInLobbyResponse;
import com.mgee.netty.server.protobuf.ImProto.LeaveRoomResponse;
import com.mgee.netty.server.protobuf.ImProto.LobbyInfoRsp;
import com.mgee.netty.server.protobuf.ImProto.OnRoomInfoResponse;
import com.mgee.netty.server.protobuf.ImProto.PushTaskInfoRequest;
import com.mgee.netty.server.protobuf.ImProto.PushTaskInfoRsp;
import com.mgee.netty.server.protobuf.ImProto.RemovePlayer;
import com.mgee.netty.server.protobuf.ImProto.StartGameRsp;
import com.mgee.netty.server.protobuf.ImProto.TransmissionSyncRequest;
import com.mgee.netty.server.protobuf.ImProto.TransmissionSyncRsp;
import com.mgee.netty.server.protobuf.ImProto.UpdateRoomInfoRequest;
import com.mgee.netty.server.util.MessageBuilder;

import lombok.extern.slf4j.Slf4j;

/**
 * 
 * @author mileswan
 *
 */
@Service
@Slf4j
public class LobbyRoomService {
	
	@Autowired
	private SessionManager sessionManager;
	
	
	public void joinRoom(ImMsg imMsg, IoSession currSession) {
		
		try {
			ChatUserInfo userInfo = currSession.getUser();
			if(userInfo == null) {
				currSession.sendMessage(MessageBuilder.buildErrorResponse(imMsg, MessagingConst.RESPONSE_ERR_CODE_400, "用户未登录!"));
				return;
			}
			String sender_uid = userInfo.getUid();
			JoiRoomInLobbyRequest joinRoomRequest = imMsg.getMsg().unpack(JoiRoomInLobbyRequest.class);
			
			int maxUser = joinRoomRequest.getRoomMaxplayer();
			String roomName = joinRoomRequest.getRoomName();
			
			LobbyInfo lobbyInfo = SessionManager.userId2Lobbies.get(sender_uid);
			if(lobbyInfo == null) {
				currSession.sendMessage(MessageBuilder.buildErrorResponse(imMsg, MessagingConst.RESPONSE_ERR_CODE_400, "必须先加入大厅"));
				return;
			}
			Map<String, LobbyRoomInfo> lobbyRoomInfos = lobbyInfo.getRoomsInfo();
			if(lobbyRoomInfos == null) {
				lobbyRoomInfos = new ConcurrentHashMap<String, LobbyRoomInfo>();
			}
			
			//判断当前是否已在其他房间
			LobbyRoomInfo roomInfo = SessionManager.userId2LobbyRooms.get(sender_uid);
			if(roomInfo != null) {
				if(StringUtils.equals(roomName, roomInfo.getName())) {
					currSession.sendMessage(MessageBuilder.buildErrorResponse(imMsg, MessagingConst.RESPONSE_ERR_CODE_400, "当前已经在此房间中"));
					return;
				}else {
					currSession.sendMessage(MessageBuilder.buildErrorResponse(imMsg, MessagingConst.RESPONSE_ERR_CODE_400, "当前已经在其他房间"+roomInfo.getName()+"中"));
					return;
				}
			}
			
			Map<String, ChatUserInfo> roomUserMap = SessionManager.lobbyRoomId2Users.get(roomName);
			roomInfo = lobbyRoomInfos.get(roomName);
			if(roomUserMap == null) { // 创建房间，默认为房主
				roomUserMap = new ConcurrentHashMap<String, ChatUserInfo>();
				userInfo.setIsMaster(true);
				roomInfo = null;
				roomInfo = new LobbyRoomInfo();
				roomInfo.setMaxusers(maxUser);
				roomInfo.setName(roomName);
				roomInfo.setUserlist(roomUserMap);
			}else {
				userInfo.setIsMaster(false);
				maxUser = roomInfo.getMaxusers();
			}
			
			//检查人数上限
			if(roomUserMap.size() >= maxUser) {
				currSession.sendMessage(MessageBuilder.buildErrorResponse(imMsg, MessagingConst.RESPONSE_ERR_CODE_400, "超出人数上限."));
				return;
			}
			
			roomUserMap.put(sender_uid, userInfo);
			roomInfo.setPeopleMember(roomUserMap.size());
			
			lobbyRoomInfos.put(roomName, roomInfo);
			SessionManager.lobbyRoomId2Users.put(roomName, roomUserMap);
			SessionManager.userId2LobbyRooms.put(sender_uid, roomInfo);
			
			//广播房间信息更新消息
			OnRoomInfoResponse.Builder onRoomInfoBuilder = OnRoomInfoResponse.newBuilder();
			onRoomInfoBuilder.setRoleInfo(MessageBuilder.buildRoomInfoMsg(roomInfo));
			ImMsg.Builder imMsgOnRoomInfoBuilderBuilder = ImMsg.newBuilder();
            
			imMsgOnRoomInfoBuilderBuilder.setMsg(Any.pack(onRoomInfoBuilder.build()));
			imMsgOnRoomInfoBuilderBuilder.setId(imMsg.getId());
			sessionManager.sendMessageToAllLobbyRoomUsers(imMsgOnRoomInfoBuilderBuilder.build(), sender_uid);
			
			//广播大厅信息更新消息
			LobbyInfoRsp.Builder lobbyInfoRspBuilder = LobbyInfoRsp.newBuilder();
			lobbyInfoRspBuilder.addAllMRoomInlobby(MessageBuilder.buildRoomInfoListMsg(lobbyInfo.getRoomsInfo().values()));
			ImMsg.Builder imMsglobbyInfoBuilder = ImMsg.newBuilder();
            
			imMsglobbyInfoBuilder.setMsg(Any.pack(lobbyInfoRspBuilder.build()));
			imMsglobbyInfoBuilder.setId(imMsg.getId());
			sessionManager.sendMessageToLobbyUsers(imMsglobbyInfoBuilder.build(), sender_uid);
			
			//返回JoinRoom Response消息
			JoinRoomInLobbyResponse.Builder joinRoomResponseBuilder = JoinRoomInLobbyResponse.newBuilder();
    		ImMsg.Builder imMsgBuilder = ImMsg.newBuilder();
    		joinRoomResponseBuilder.setResult(true);
    		joinRoomResponseBuilder.setIsMaster(userInfo.getIsMaster());
    		joinRoomResponseBuilder.setDescription("加入房间成功");
            
            imMsgBuilder.setMsg(Any.pack(joinRoomResponseBuilder.build()));
            imMsgBuilder.setId(imMsg.getId());
            
            //发送反馈消息
	        currSession.sendMessage(imMsgBuilder.build());
	        
		}catch(Exception e) {
			log.error("Join LobbyRoom时发生异常, ", e);
		}
		
	}
	
	public void leaveRoom(ImMsg imMsg, IoSession currSession) {
		
		try {
			if(currSession.getUser() == null) {
				currSession.sendMessage(MessageBuilder.buildErrorResponse(imMsg, MessagingConst.RESPONSE_ERR_CODE_400, "用户未登录!"));
				return;
			}
			String sender_uid = currSession.getUser().getUid();
			
			LobbyRoomInfo roomInfo = SessionManager.userId2LobbyRooms.get(sender_uid);
			if(roomInfo == null) {
				currSession.sendMessage(MessageBuilder.buildErrorResponse(imMsg, MessagingConst.RESPONSE_ERR_CODE_400, "用户未在任何房间."));
				return;
			}

			processLeaveRoom(currSession.getUser(), roomInfo);
			
	    	// 按照定义的数据结构，创建返回消息对象  
//			LeaveRoomResponse.Builder leaveRoomResponseBuilder = LeaveRoomResponse.newBuilder();
//    		ImMsg.Builder imMsgBuilder = ImMsg.newBuilder();
//    		leaveRoomResponseBuilder.setPlayerName(sender_uid);
//    		leaveRoomResponseBuilder.setIsMaster(currSession.getUser().getIsMaster());
//            
//            imMsgBuilder.setMsg(Any.pack(leaveRoomResponseBuilder.build()));
//            imMsgBuilder.setId(imMsg.getId());
//	        //发送反馈消息
//	        currSession.sendMessage(imMsgBuilder.build());
	        
		}catch(Exception e) {
			log.error("Leave Lobby Room时发生异常, ", e);
		}
		
	}
	
	public void processLeaveRoom(ChatUserInfo currUser, LobbyRoomInfo roomInfo) {
		
		Map<String, ChatUserInfo> roomUserMap = SessionManager.lobbyRoomId2Users.get(roomInfo.getName());
		String uid = currUser.getUid();
		if(roomUserMap != null && roomUserMap.get(uid) != null) {
			
			//广播房间所有人包括自己leaveRoomResponse消息
			LeaveRoomResponse.Builder leaveRoomResponseBuilder = LeaveRoomResponse.newBuilder();
    		ImMsg.Builder imMsgLeaveRoomRspBuilder = ImMsg.newBuilder();
    		leaveRoomResponseBuilder.setPlayerName(uid);
    		leaveRoomResponseBuilder.setIsMaster(currUser.getIsMaster());
            
            imMsgLeaveRoomRspBuilder.setMsg(Any.pack(leaveRoomResponseBuilder.build()));
            sessionManager.sendMessageToAllLobbyRoomUsers(imMsgLeaveRoomRspBuilder.build(), uid);
			
            //当前用户从房间map中删除
			ChatUserInfo removedUser = roomUserMap.remove(uid);
			if(removedUser != null && removedUser.getPlayerPack() != null) {
				
				//广播removePlayer消息
				RemovePlayer.Builder removePlayerBuilder = RemovePlayer.newBuilder();
				removePlayerBuilder.setPlayerPack(removedUser.getPlayerPack());
				ImMsg.Builder imMsgRemovePlayerBuilder = ImMsg.newBuilder();
				imMsgRemovePlayerBuilder.setMsg(Any.pack(removePlayerBuilder.build()));
				
				removedUser.setLobbyRoomPlayerPack(null);
				sessionManager.sendMessageToLobbyRoomPlayers(imMsgRemovePlayerBuilder.build(), uid, false);
			}
			roomInfo.setPeopleMember(roomUserMap.size());
			if(roomUserMap.isEmpty()) {
				//销毁房间数据
				SessionManager.lobbyRoomId2Users.remove(roomInfo.getName());
				LobbyInfo lobbyInfo = SessionManager.userId2Lobbies.get(uid);
				if(lobbyInfo != null) {
					lobbyInfo.getRoomsInfo().remove(roomInfo.getName());
				}
			}
			
			//广播房间信息更新消息
			if(roomInfo != null) {
				OnRoomInfoResponse.Builder onRoomInfoBuilder = OnRoomInfoResponse.newBuilder();
				onRoomInfoBuilder.setRoleInfo(MessageBuilder.buildRoomInfoMsg(roomInfo));
				ImMsg.Builder imMsgOnRoomInfoBuilderBuilder = ImMsg.newBuilder();
	            
				imMsgOnRoomInfoBuilderBuilder.setMsg(Any.pack(onRoomInfoBuilder.build()));
				sessionManager.sendMessageToLobbyRoomUsers(imMsgOnRoomInfoBuilderBuilder.build(), uid);
			}
			
			//广播大厅信息更新消息
			LobbyInfoRsp.Builder lobbyInfoRspBuilder = LobbyInfoRsp.newBuilder();
			lobbyInfoRspBuilder.addAllMRoomInlobby(MessageBuilder.buildRoomInfoListMsg(SessionManager.userId2Lobbies.get(uid).getRoomsInfo().values()));
			ImMsg.Builder imMsglobbyInfoBuilder = ImMsg.newBuilder();
            
			imMsglobbyInfoBuilder.setMsg(Any.pack(lobbyInfoRspBuilder.build()));
			sessionManager.sendMessageToAllLobbyUsers(imMsglobbyInfoBuilder.build(), uid);
		}
		
		SessionManager.userId2LobbyRooms.remove(uid);
	}
	
	
	public void updateRoomInfo(ImMsg imMsg, IoSession currSession) {
		
		try {
			if(currSession.getUser() == null) {
				currSession.sendMessage(MessageBuilder.buildErrorResponse(imMsg, MessagingConst.RESPONSE_ERR_CODE_400, "用户未登录!"));
				return;
			}
			String sender_uid = currSession.getUser().getUid();
			UpdateRoomInfoRequest updateRoomRequest = imMsg.getMsg().unpack(UpdateRoomInfoRequest.class);
			
			LobbyRoomInfo roomInfo = SessionManager.userId2LobbyRooms.get(sender_uid);
			if(roomInfo == null) {
				currSession.sendMessage(MessageBuilder.buildErrorResponse(imMsg, MessagingConst.RESPONSE_ERR_CODE_400, "用户未在任何房间!"));
				return;
			}
			
			//更新房间信息
			roomInfo.setStatus(updateRoomRequest.getRoomStatus());
			roomInfo.setOperatorsNumber(updateRoomRequest.getOperatorsNumber());
			roomInfo.setViewersNumber(updateRoomRequest.getViewersNumber());
			roomInfo.setCurrentTaskIndex(updateRoomRequest.getCurrentTaskIndex());
			roomInfo.setUserWithRole(updateRoomRequest.getUserWithRole());
			
			//广播房间信息更新消息
			OnRoomInfoResponse.Builder onRoomInfoBuilder = OnRoomInfoResponse.newBuilder();
			onRoomInfoBuilder.setRoleInfo(MessageBuilder.buildRoomInfoMsg(roomInfo));
			ImMsg.Builder imMsgOnRoomInfoBuilderBuilder = ImMsg.newBuilder();
            
			imMsgOnRoomInfoBuilderBuilder.setMsg(Any.pack(onRoomInfoBuilder.build()));
			imMsgOnRoomInfoBuilderBuilder.setId(imMsg.getId());
			sessionManager.sendMessageToLobbyRoomUsers(imMsgOnRoomInfoBuilderBuilder.build(), sender_uid);
			
			//广播大厅信息更新消息
			LobbyInfoRsp.Builder lobbyInfoRspBuilder = LobbyInfoRsp.newBuilder();
			lobbyInfoRspBuilder.addAllMRoomInlobby(MessageBuilder.buildRoomInfoListMsg(SessionManager.userId2Lobbies.get(sender_uid).getRoomsInfo().values()));
			ImMsg.Builder imMsglobbyInfoBuilder = ImMsg.newBuilder();
            
			imMsglobbyInfoBuilder.setMsg(Any.pack(lobbyInfoRspBuilder.build()));
			imMsglobbyInfoBuilder.setId(imMsg.getId());
			sessionManager.sendMessageToLobbyUsers(imMsglobbyInfoBuilder.build(), sender_uid);
            
            //发送反馈消息
	        currSession.sendMessage(imMsgOnRoomInfoBuilderBuilder.build());
	        
		}catch(Exception e) {
			log.error("Update RoomInfo时发生异常, ", e);
		}
		
	}
	
	public void startGame(ImMsg imMsg, IoSession currSession) {
		
		try {
			if(currSession.getUser() == null) {
				currSession.sendMessage(MessageBuilder.buildErrorResponse(imMsg, MessagingConst.RESPONSE_ERR_CODE_400, "用户未登录!"));
				return;
			}
			String sender_uid = currSession.getUser().getUid();
			//StartGameRequest startGameRequest = imMsg.getMsg().unpack(StartGameRequest.class);
			
			LobbyRoomInfo roomInfo = SessionManager.userId2LobbyRooms.get(sender_uid);
			if(roomInfo == null) {
				currSession.sendMessage(MessageBuilder.buildErrorResponse(imMsg, MessagingConst.RESPONSE_ERR_CODE_400, "用户未在任何房间!"));
				return;
			}
			
			//广播开始游戏rsp消息
			StartGameRsp.Builder startGameRspBuilder = StartGameRsp.newBuilder();
			ImMsg.Builder imMsgRspBuilder = ImMsg.newBuilder();
            
			imMsgRspBuilder.setMsg(Any.pack(startGameRspBuilder.build()));
			imMsgRspBuilder.setId(imMsg.getId());
			sessionManager.sendMessageToLobbyRoomUsers(imMsgRspBuilder.build(), sender_uid);
            
            //发送反馈消息
	        currSession.sendMessage(imMsgRspBuilder.build());
	        
		}catch(Exception e) {
			log.error("Start Game时发生异常, ", e);
		}
		
	}
	
	public void pushTaskInfo(ImMsg imMsg, IoSession currSession) {
		
		try {
			if(currSession.getUser() == null) {
				currSession.sendMessage(MessageBuilder.buildErrorResponse(imMsg, MessagingConst.RESPONSE_ERR_CODE_400, "用户未登录!"));
				return;
			}
			String sender_uid = currSession.getUser().getUid();
			PushTaskInfoRequest pushTaskRequest = imMsg.getMsg().unpack(PushTaskInfoRequest.class);
			
			LobbyRoomInfo roomInfo = SessionManager.userId2LobbyRooms.get(sender_uid);
			if(roomInfo == null) {
				currSession.sendMessage(MessageBuilder.buildErrorResponse(imMsg, MessagingConst.RESPONSE_ERR_CODE_400, "用户未在任何房间!"));
				return;
			}
			
			//更新房间信息
			roomInfo.setCurrentTaskIndex(pushTaskRequest.getTaskinfo().getTaskid());
			
			//广播推送任务消息
			//TaskInfo.Builder taskInfoBuilder = TaskInfo.newBuilder();
			ImMsg.Builder imMsgBroadBuilder = ImMsg.newBuilder();
            
			imMsgBroadBuilder.setMsg(Any.pack(pushTaskRequest.getTaskinfo()));
			imMsgBroadBuilder.setId(imMsg.getId());
			sessionManager.sendMessageToLobbyRoomUsers(imMsgBroadBuilder.build(), sender_uid);
            
            //发送反馈消息
			PushTaskInfoRsp.Builder pushTaskInfoRspBuilder = PushTaskInfoRsp.newBuilder();
    		ImMsg.Builder imMsgRspBuilder = ImMsg.newBuilder();
    		pushTaskInfoRspBuilder.setTaskid(pushTaskRequest.getTaskinfo());
            
    		imMsgRspBuilder.setMsg(Any.pack(pushTaskInfoRspBuilder.build()));
    		imMsgRspBuilder.setId(imMsg.getId());
	        currSession.sendMessage(imMsgRspBuilder.build());
	        
		}catch(Exception e) {
			log.error("PushTaskInfo时发生异常, ", e);
		}
		
	}
	
	public void transmissionSync(ImMsg imMsg, IoSession currSession) {
		
		try {
			if(currSession.getUser() == null) {
				currSession.sendMessage(MessageBuilder.buildErrorResponse(imMsg, MessagingConst.RESPONSE_ERR_CODE_400, "用户未登录!"));
				return;
			}
			String sender_uid = currSession.getUser().getUid();
			TransmissionSyncRequest syncRequest = imMsg.getMsg().unpack(TransmissionSyncRequest.class);
			
			LobbyRoomInfo roomInfo = SessionManager.userId2LobbyRooms.get(sender_uid);
			if(roomInfo == null) {
				currSession.sendMessage(MessageBuilder.buildErrorResponse(imMsg, MessagingConst.RESPONSE_ERR_CODE_400, "用户未在任何房间!"));
				return;
			}
			if(syncRequest.getPos() == null) {
				currSession.sendMessage(MessageBuilder.buildErrorResponse(imMsg, MessagingConst.RESPONSE_ERR_CODE_400, "请求的参数错误,pos不能为空!"));
				return;
			}
			
			//广播Rsp消息
			TransmissionSyncRsp.Builder syncRspBuilder = TransmissionSyncRsp.newBuilder();
			syncRspBuilder.setPos(syncRequest.getPos());
            
			ImMsg.Builder imMsgBroadBuilder = ImMsg.newBuilder();
			imMsgBroadBuilder.setMsg(Any.pack(syncRspBuilder.build()));
			imMsgBroadBuilder.setId(imMsg.getId());
			sessionManager.sendMessageToAllLobbyRoomUsers(imMsgBroadBuilder.build(), sender_uid);
            
            //发送反馈消息
//			PushTaskInfoRsp.Builder pushTaskInfoRspBuilder = PushTaskInfoRsp.newBuilder();
//    		ImMsg.Builder imMsgRspBuilder = ImMsg.newBuilder();
//    		pushTaskInfoRspBuilder.setTaskid(pushTaskRequest.getTaskinfo());
//            
//    		imMsgRspBuilder.setMsg(Any.pack(pushTaskInfoRspBuilder.build()));
//    		imMsgRspBuilder.setId(imMsg.getId());
//	        currSession.sendMessage(imMsgRspBuilder.build());
	        
		}catch(Exception e) {
			log.error("transmissionSync时发生异常, ", e);
		}
		
	}
	
}
